#define _CRT_SECURE_NO_WARNINGS
#include "Dumper.h"
#include "..\main.h"
#include <windows.h>

CDumper::CDumper(CMaster * Master, CTimer * Timer, CGParser * Parser): 
Master(Master), Timer(Timer), CNT(-1), No(0), Parser(Parser)
{
	InitializeCriticalSection(&CSPrintState);
	Spins[0].Time = -1;
	Spins[1].Time = -1;
	Spins[2].Time = -1;
	Spins[0].Cmd = (CCommand)-1;
	Spins[1].Cmd = (CCommand)-1;
	Spins[2].Cmd = (CCommand)-1;
	Spins[0].TimerPos = (DWORD *) -1;
	Spins[1].TimerPos = (DWORD *) -1;
	Spins[2].TimerPos = (DWORD *) -1;
};


void CDumper::PrintState(int Src, const char * Text, char L, DWORD * q)
{
	//return;
	EnterCriticalSection(&CSPrintState);
	if(Src == -3)
	{
		No = 0;
		printf("\n-----------------------------<< %s >>--------------------------------------", Text);
	}
	if(!(No++ & 0x1F))
	printf("\n    CNT    Time | MDst MExe| Exe0 Cmd AEIDB TD TS TP| Exe1 Cmd AEIDB TD TS TP| Exe2 Cmd AEIDB TD TS TP|");
	//printf("\n    CNT    Time | MDst MSrc| Time  Src0 Cmd AEIDB TD TS TP| Time  Src1 Cmd AEIDB TD TS TP| Time  Src2 Cmd AEIDB TD TS TP|");

	char b[200], * s = b;
	*(s++) = '\n';
	if(CNT != Timer->CNT)
	{
		CNT = Timer->CNT;
		s += sprintf(s, "%9d %6.3f", CNT, (double)CNT / CK_INT);
	}
	else {memset(s, '    ', 16); s += 16;}
	*(s++) = '|';
	*(s++) = ' ';
	*(s++) = (Src == -2) ? 'W' : ' ';
	if(Sch != Master->SchCtr)
	{
		Sch = Master->SchCtr;
		s += sprintf(s, "%3d", Sch);
	} else {memset(s, '    ', 3); s += 3;}
	*(s++) = ' ';
	*(s++) = (Src == -1) ? L : ' ';
	if(Exe != Master->ExecCtr)
	{
		Exe = Master->ExecCtr;
		s += sprintf(s, "%3d", Exe);
	} else {memset(s, '    ', 3); s += 3;}
	*(s++) = '|';
	for(int x = 0; x < 3; x++)
	{
		/*if(Spins[x].Time != Master->Spins[x].Time)
		{
			Spins[x].Time = Master->Spins[x].Time;
			s += sprintf(s, "%6.3f", (double)Spins[x].Time / CK_INT);

		} else {memset(s, '    ', 6); s += 6;}*/
		*(s++) = (Src == x) ? L : ' ';
		*(s++) = ' ';
		//if(Spins[x].QSrc != Master->Spins[x].QSrc)
		{
			//Spins[x].QSrc = Master->Spins[x].QSrc;
			s += sprintf(s, "%3d", Master->Spins[x].ExecCtr);
		} //else {memset(s, '    ', 3); s += 3;}

		if(Master->Spins[x].Command >= CMD_G0 || Spins[x].Cmd != Master->Spins[x].Command)
		{
			switch(Spins[x].Cmd = Master->Spins[x].Command)
			{
			case CMD_OFF: *(DWORD *)s = 'FFO '; break;
			case CMD_STOP: *(DWORD *)s = 'POTS'; break;
			case CMD_G0: *(DWORD *)s = ' 0G '; break;
			case CMD_G1: *(DWORD *)s = ' 1G '; break;
			case CMD_BASE: *(DWORD *)s = 'ESAB'; break;
			}
		} else *(DWORD *)s = '    ';
		s += 4;

		*(s++) = ' ';


		*(s++) = (Master->ActiveMask & (1 << x)) ? 'A' : ' ';
		*(s++) = Timer->Channels[x].Enabled ? 'E' : 'D';
		*(s++) = (Master->Irq & (1 << x)) ? 'I' : ' ';
		*(s++) = Timer->Channels[x].Dir ? '+' : '-';
		if(Master->Spins[x].Block == BLK_BOTTOM) *s = 'B';
		else
		if(Master->Spins[x].Block == BLK_TOP) *s = 'T';
		else *s = ' ';
		s++;

		if(Spins[x].TimerDst != Master->Spins[x].TimerDst)
		{
			Spins[x].TimerDst = Master->Spins[x].TimerDst;
			s += sprintf(s, "%3d", Spins[x].TimerDst - Master->Spins[x].TimerData);
		} else {memset(s, '    ', 3); s += 3;}

		if(Spins[x].TimerSrc != Master->Spins[x].DMA->Src)
		{
			Spins[x].TimerSrc = Master->Spins[x].DMA->Src;
			s += sprintf(s, "%3d", Spins[x].TimerSrc - Master->Spins[x].TimerData);
		} else {memset(s, '    ', 3); s += 3;}

		if(Spins[x].TimerPos != Master->Spins[x].TimPos)
		{
			Spins[x].TimerPos = Master->Spins[x].TimPos;
			if(!Spins[x].TimerPos)
				s += sprintf(s, " ##");
			else
				s += sprintf(s, "%3d", Spins[x].TimerPos - Master->Spins[x].TimerData);
		} else {memset(s, '    ', 3); s += 3;}
		*(s++) = '|';
	}
//|%4d %4d %4d %4d %4d ", , Master.QDst - Master.Queue, Master.QSrc - Master.Queue, Master.Spins[0].QSrc - Master.Queue, Master.Spins[1].QSrc - Master.Queue, Master.Spins[2].QSrc - Master.Queue);

	strcpy(s, Text);
	s += strlen(Text);
	if(q)
	{
		if(L == 'W')
		{
			int l = Parser->cmde - Parser->cmdh;
			if(l > 50) l = 50;
			memcpy(s, Parser->cmdh, l);
			s += l;
			*s = 0;
			QWORD * qq = Queue + (q - Master->Queue);
			char * a = (char *)qq;
			char * e = ((char *)Queue) + sizeof(Queue) - 1;
			if(qq > Queue)
			{
				a[-2] = '?';
				a[-1] = 0;
			}
			for(const char * s = Parser->cmdh; s < Parser->cmde && a < e; s++, a++)
				*a = *s;
			*a = 0;
		}
		else
		{
			char * a = (char *)(Queue + (q - Master->Queue));
			for(int x = 0; x < 40; x++, s++)
			{
				if(!(*s = a[x])) break;
			}
		}
	}
	//*(s++) = '0';
	printf(b);
	LeaveCriticalSection(&CSPrintState);
}